#include <HAL/driverManager.h>
#include <utitl/logger.h>
#include <HAL/hal.h>

#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <stdio.h>
#include <dlfcn.h>

#define PATH "/opt/ECG/lib/driver/"

using namespace ECG::Utitl;

namespace ECG
{
    namespace HAL
    {

    DriverManagerPtr DriverManager::m_driverManager;

    void DriverManager::setDrvierPath(std::string path)
    {
        this->path = path;

    }

    bool DriverManager::loadDrivers()
    {
        log_debug() << "drivers path = " << path;
        DIR *dir;
        dir = opendir(path.c_str());
        if(dir == NULL)
        {
            log_error() << "fail to open dir:" << path;
            return false;
        }
        struct dirent *diren;
        while((diren = readdir(dir)) != NULL)
        {
            //log_debug() << diren->d_name;
            printf("file: %s\n", diren->d_name);
            std::string tail(diren->d_name);
            if(tail == ".." || tail == ".") continue;
            std::string fullPath;
            fullPath  = path + tail;
            DriverPtr driver;
            void *handle = dlopen(fullPath.c_str(), RTLD_LAZY);
            log_debug() << "full path = " << fullPath;
            if (handle == NULL)
            {
                log_error() << "unable open file:" << fullPath;
                return false;
            }
            DriverPtr (*createClass)() = (DriverPtr(*)())dlsym(handle, "createClass");
            if (NULL == createClass)
            {
                log_error() << "unable find method: createClass";
                return false;
            }
            driver = createClass();
            driverVec.push_back(driver);
            log_debug() << "push driver";
        }
        log_debug() << driverVec.size();
        closedir(dir);
        return true;
    }

    DriverManagerPtr DriverManager::instance()
    {
        if(!m_driverManager.get())
        {
            m_driverManager.reset(new DriverManager(PATH));
        }
        return m_driverManager;
    }

    DriverManager::~DriverManager()
    {

    }

    DriverManager::DriverManager(std::string drvPath) : path(drvPath)
    {

    }
    
    }
}